#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
B站音频信息获取模块
主要用于获取视频的音频流信息和音频相关数据
"""

import requests
import re
import json
from typing import Dict, Optional, Any, List
from .config import HEADERS
from .getbilivideo import BiliVideoFetcher


class BiliAudioFetcher(BiliVideoFetcher):
    """B站音频信息获取器，继承自视频获取器"""
    
    def __init__(self):
        super().__init__()
        # 音频相关的请求头
        self.audio_headers = {
            **self.headers,
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
        }
    
    def get_audio_info(self, url: str) -> Dict[str, Any]:
        """获取B站视频的音频信息
        
        Args:
            url: B站视频URL
            
        Returns:
            包含音频信息的字典
        """
        # 首先获取基础视频信息
        video_info = self.get_video_info(url)
        
        # 提取音频相关信息
        audio_info = {
            'bvid': video_info['bvid'],
            'title': video_info['title'],
            'author': video_info['author'],
            'duration': video_info['duration'],
            'video_url': video_info['video_url'],
            'audio_quality_options': [],
            'estimated_audio_size': 0,
            'audio_format': 'mp3',  # 默认格式
            'audio_bitrate': 'unknown'
        }
        
        try:
            # 尝试获取更详细的音频流信息
            audio_streams = self._get_audio_streams(video_info['bvid'])
            if audio_streams:
                audio_info['audio_quality_options'] = audio_streams
                
        except Exception as e:
            print(f"获取音频流信息时出错: {e}")
        
        return audio_info
    
    def _get_audio_streams(self, bvid: str) -> List[Dict[str, Any]]:
        """获取音频流信息
        
        注意：这需要调用B站的API，可能需要登录状态
        """
        # 这里是一个示例实现，实际需要根据B站API进行调整
        audio_streams = []
        
        try:
            # 构造API请求URL（这是一个示例，实际API可能不同）
            api_url = f"https://api.bilibili.com/x/web-interface/view?bvid={bvid}"
            
            response = requests.get(api_url, headers=self.audio_headers, timeout=15)
            response.raise_for_status()
            
            data = response.json()
            if data.get('code') == 0:
                video_data = data.get('data', {})
                
                # 从视频数据中提取音频相关信息
                duration = video_data.get('duration', 0)
                
                # 估算不同质量的音频大小和比特率
                quality_options = [
                    {'quality': 'high', 'bitrate': '320kbps', 'format': 'mp3'},
                    {'quality': 'medium', 'bitrate': '192kbps', 'format': 'mp3'},
                    {'quality': 'low', 'bitrate': '128kbps', 'format': 'mp3'}
                ]
                
                for option in quality_options:
                    bitrate_num = int(option['bitrate'].replace('kbps', ''))
                    estimated_size = (duration * bitrate_num * 1000) // 8  # 字节
                    
                    audio_streams.append({
                        'quality': option['quality'],
                        'bitrate': option['bitrate'],
                        'format': option['format'],
                        'estimated_size_bytes': estimated_size,
                        'estimated_size_mb': round(estimated_size / (1024 * 1024), 2)
                    })
                    
        except Exception as e:
            print(f"获取音频流信息失败: {e}")
        
        return audio_streams
    
    def get_audio_download_info(self, url: str, quality: str = 'medium') -> Dict[str, Any]:
        """获取音频下载信息
        
        Args:
            url: B站视频URL
            quality: 音频质量 ('high', 'medium', 'low')
            
        Returns:
            音频下载信息字典
        """
        bvid = self.extract_bvid(url)
        if not bvid:
            raise ValueError("无法从URL中提取BVID")
        
        audio_info = self.get_audio_info(url)
        
        # 查找指定质量的音频选项
        selected_option = None
        for option in audio_info.get('audio_quality_options', []):
            if option['quality'] == quality:
                selected_option = option
                break
        
        if not selected_option and audio_info.get('audio_quality_options'):
            selected_option = audio_info['audio_quality_options'][0]  # 默认选择第一个
        
        download_info = {
            'bvid': bvid,
            'title': audio_info['title'],
            'author': audio_info['author'],
            'video_url': audio_info['video_url'],
            'selected_quality': selected_option,
            'download_url': None,  # 需要进一步的API调用获取
            'message': 'B站音频下载需要复杂的认证和解析过程，建议使用专门的下载工具',
            'suggested_tools': ['you-get', 'youtube-dl', 'yt-dlp']
        }
        
        return download_info
    
    def extract_audio_metadata(self, url: str) -> Dict[str, Any]:
        """提取音频元数据信息
        
        Args:
            url: B站视频URL
            
        Returns:
            音频元数据字典
        """
        video_info = self.get_video_info(url)
        
        metadata = {
            'title': video_info['title'],
            'artist': video_info['author'],
            'duration_seconds': video_info['duration'],
            'duration_formatted': self._format_duration(video_info['duration']),
            'source': 'bilibili',
            'source_url': video_info['video_url'],
            'bvid': video_info['bvid'],
            'tags': video_info.get('tags', []),
            'description': video_info.get('description', ''),
            'upload_time': video_info.get('upload_time', ''),
            'view_count': video_info.get('view_count', 0)
        }
        
        return metadata
    
    def _format_duration(self, seconds: int) -> str:
        """格式化时长
        
        Args:
            seconds: 秒数
            
        Returns:
            格式化的时长字符串 (MM:SS 或 HH:MM:SS)
        """
        if seconds < 3600:  # 小于1小时
            minutes = seconds // 60
            secs = seconds % 60
            return f"{minutes:02d}:{secs:02d}"
        else:  # 大于等于1小时
            hours = seconds // 3600
            minutes = (seconds % 3600) // 60
            secs = seconds % 60
            return f"{hours:02d}:{minutes:02d}:{secs:02d}"


def get_bili_audio_info(url: str) -> Dict[str, Any]:
    """获取B站视频音频信息的便捷函数
    
    Args:
        url: B站视频URL
        
    Returns:
        音频信息字典
    """
    fetcher = BiliAudioFetcher()
    return fetcher.get_audio_info(url)


def get_bili_audio_download_info(url: str, quality: str = 'medium') -> Dict[str, Any]:
    """获取B站音频下载信息的便捷函数
    
    Args:
        url: B站视频URL
        quality: 音频质量
        
    Returns:
        音频下载信息字典
    """
    fetcher = BiliAudioFetcher()
    return fetcher.get_audio_download_info(url, quality)


def get_bili_audio_metadata(url: str) -> Dict[str, Any]:
    """获取B站音频元数据的便捷函数
    
    Args:
        url: B站视频URL
        
    Returns:
        音频元数据字典
    """
    fetcher = BiliAudioFetcher()
    return fetcher.extract_audio_metadata(url)


if __name__ == "__main__":
    # 测试代码
    test_url = "https://www.bilibili.com/video/BV13M4y1t7PE"
    try:
        print("=== 音频信息 ===")
        audio_info = get_bili_audio_info(test_url)
        for key, value in audio_info.items():
            print(f"{key}: {value}")
        
        print("\n=== 音频元数据 ===")
        metadata = get_bili_audio_metadata(test_url)
        for key, value in metadata.items():
            print(f"{key}: {value}")
            
    except Exception as e:
        print(f"获取音频信息失败: {e}")